package scanner;

import static scanner.TokenType.*;

%%

%public
%class Scanner
%function nextToken
%type Token

%{ 
private String tempString;
private int stringCol;
private int stringLine;
%}


%line
%column
%caseless

LineDelimiter = \n|\r|\r\n
Whitespace = {LineDelimiter} | [\t" "]
an = [A-Za-z0-9]
a  = [A-Za-z]

%state STRINGS

%%

<YYINITIAL> {
    {Whitespace}		  {}
	/*Kommentar*/
	"//".*{LineDelimiter} {}
    /*Keywords*/
    "OF"        |
    "THEN"      |
    "DO"        |
    "PRINT"     |
    "READ"      |
    "END"       |
    "ELSE"      |
    "ELSIF"     |
    "IF"        |
    "WHILE"     |
    "REPEAT"    |
    "UNTIL"     |
    "ARRAY"     |
    "RECORD"    |
    "CONST"     |
    "TYPE"      |
    "VAR"       |
    "PROCEDURE" |
    "BEGIN"     |
    "MODULE"    { return new Token(KEYWORD, yytext().toUpperCase(), yyline, yycolumn); }

    {a}{an}*    { return new Token(IDENTIFIER, yytext(), yyline, yycolumn); }
    [0-9]+      { return new Token(INTEGER, yytext(), yyline, yycolumn); }
    
    /*operators*/
    "*"         |
    "+"         |
    "-"         |
    "/"         |
    ":="        |
    "="         |
    "#"         |
    "<"         |
    "<="        |
    ">"         |
    ">="        |
    "."         |
    ","         |
    ":"         |
    "("         |
    ")"         |
    "["         |
    "]"         |
    ";"         { return new Token(OPERATOR, yytext(), yyline, yycolumn); }

    \"          { tempString = ""; stringCol = yycolumn; stringLine = yyline; yybegin(STRINGS); }
    .           { return new Token(UNKNOWN, yytext(), yyline, yycolumn); }
}

<STRINGS> {
    "\\\\"      { tempString += "\\"; }
    "\\\""      { tempString += "\""; }
    "\\n"       { tempString += "\n"; }
    "\\r"       { tempString += "\r"; }
    "\\t"       { tempString += "\t"; }
    \"          { yybegin(YYINITIAL); return new Token(STRING, tempString, stringLine, stringCol); }
    .           { tempString += yytext(); }
}

<<EOF>>     { return new Token(EOF,""); }